/*
 * Copyright 2018 Zhongan.com All right reserved. This software is the
 * confidential and proprietary information of Zhongan.com ("Confidential
 * Information"). You shall not disclose such Confidential Information and shall
 * use it only in accordance with the terms of the license agreement you entered
 * into with Zhongan.com.
 */

package com.zhongan.cloud.gateway.filter.previous;

import java.net.URI;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.stereotype.Service;
import org.springframework.web.util.UriComponentsBuilder;

/**
 * 原有网关实现
 *
 * @author tongyufu
 * @since 2018年7月4日 下午4:28:29
 */
@Service
public class PreviousService {

    @Autowired
    private CommonGwRoutConfigDao commonGwRoutConfigDao;

    public URI fetchTargetUri(ServerHttpRequest request) {
        Map<String, String> queryParams = request.getQueryParams().toSingleValueMap();
        String serviceName = queryParams.get("serviceName");
        String serviceVersion = queryParams.get("serviceVersion");
        String urlRoute = this.getUrlRoute(request.getURI().getHost(), request.getURI().getPath(), "");
        List<CommonGwRoutConfig> configs = commonGwRoutConfigDao.queryGwConfig(serviceName, serviceVersion, urlRoute);

        if (configs.isEmpty()) {
            throw new RuntimeException("没有找到对应的网关配置信息");
        }
        if (configs.size() > 1) {
            throw new RuntimeException("please check CommonGwRoutConfig, serviceName = " + serviceName
                    + ", serviceVersion = " + serviceVersion + ", urlRoute = " + urlRoute + "] record is more than 1");
        }
        CommonGwRoutConfig config = configs.get(0);
        UriComponentsBuilder uriComponentsBuilder = UriComponentsBuilder.fromHttpUrl(config.getAppUrl());
        for (Map.Entry<String, String> param : queryParams.entrySet()) {
            if (!StringUtils.equalsAnyIgnoreCase(param.getKey(), "serviceName", "serviceVersion")) {
                uriComponentsBuilder.queryParam(param.getKey(), param.getValue());
            }
        }
        return uriComponentsBuilder.build().toUri();
    }

    private String getUrlRoute(String serverName, String requestURI, String runEnv) {
        String urlRoute = null;
        boolean flag = false;
        if ("test".equals(runEnv)) { // 测试环境
            if ("tac-gw-itest.zhongan.com".equals(serverName)) { // 走公网加白名单的协议，To B端
                urlRoute = UrlRouteEnum.INTERNET.getValue();
            } else if ("tac-gw-api-itest.zhongan.com".equals(serverName)) { // 走公网不加白名单的协议，To C端
                urlRoute = UrlRouteEnum.API.getValue();
            } else { // 请求内网IP的时候，按 requestURI 规则进行解析
                flag = true;
            }
        } else if ("pre".equals(runEnv)) { // 预发环境
            if ("tac-gw-uat.zhongan.com".equals(serverName)) { // 走公网加白名单的协议，To B端
                urlRoute = UrlRouteEnum.INTERNET.getValue();
            } else if ("tac-gw-api-uat.zhongan.com".equals(serverName)) { // 走公网不加白名单的协议，To C端
                urlRoute = UrlRouteEnum.API.getValue();
            } else { // 走内网的协议
                urlRoute = UrlRouteEnum.INTRANET.getValue();
            }
        } else if ("prd".equals(runEnv)) { // 生产环境
            if ("tac-gw.zhongan.com".equals(serverName)) { // 走公网加白名单的协议，To B端
                urlRoute = UrlRouteEnum.INTERNET.getValue();
            } else if ("tac-gw-api.zhongan.com".equals(serverName)) { // 走公网不加白名单的协议，To C端
                urlRoute = UrlRouteEnum.API.getValue();
            } else { // 走内网的协议
                urlRoute = UrlRouteEnum.INTRANET.getValue();
            }
        } else { // 开发环境，按 requestURI 规则进行解析
            flag = true;
        }

        if (flag) { // "测试环境请求内网IP的时候"和"开发环境"，按 requestURI 规则进行解析
            if (requestURI.startsWith("/gateway/api")) {
                urlRoute = UrlRouteEnum.API.getValue();
            } else if (requestURI.startsWith("/gateway/intranet")) {
                urlRoute = UrlRouteEnum.INTRANET.getValue();
            } else {
                urlRoute = UrlRouteEnum.INTERNET.getValue();
            }
        }
        return urlRoute;
    }
}
